package com.fingard.dsp.bank.directbank.spdb12;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.directbank.spdb12.SPDB12Base;
import com.fingard.dsp.bank.directbank.spdb12.util.WtpFileUtil;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.net.MixFtp;
import com.fingard.net.SftpPortClient;
import com.fingard.text.StringHelper;

import java.io.BufferedReader;
import java.io.File;
import java.io.StringReader;
import java.text.MessageFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

import msoa.org.apache.commons.lang.StringUtils;

/**
 * 浦发银保通批量代收付
 */
public class SPDB12BatPayRec extends SPDB12Base implements IBatPayRec {
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        return d_BatPayRec(p_req1988);
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        return d_QryBatPayRec(p_req1998);
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return d_BatPayRec(p_req9188);
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return d_QryBatPayRec(p_req9198);
    }

    public RetAtsBatPayRec d_BatPayRec(ReqBatPayRec p_reqBat) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);
        retAts.reqSeqID = p_reqBat.reqBatchNO;

        try {
            // 代收付文件内容
            StringBuilder sbFileContent = new StringBuilder();
            String transCode = "1006";
            String trxCode = "UBP";
            if ("1988".equals(p_reqBat.reqHeader.transType)) {
                trxCode = "UBD";
                transCode = "1008";
            }
            Date tmpPayDateTime = getDayCutTime(p_reqBat.getPayDateTime());
            String tmpPayDate = Format.Date8Format.format(tmpPayDateTime);

            // 文件头
            String tmpReqHeader = MessageFormat.format("F※{0}※{1}※{2}※{3}※{4}※{5}※※※N\n", bankFront.corpNo, transCode, p_reqBat.totalAmt, p_reqBat.totalNum, tmpPayDate, p_reqBat.totalNum);
            sbFileContent.append(tmpReqHeader);

            // 文件明细
            while (p_reqBat.readRecord()) {
                String oppAct = p_reqBat.readedDetail.payAct;
                String oppName = p_reqBat.readedDetail.payName;
                if ("1988".equals(p_reqBat.reqHeader.transType)) {
                    oppAct = p_reqBat.readedDetail.recAct;
                    oppName = p_reqBat.readedDetail.recName;
                }

                String insuPolicyNum = p_reqBat.readedDetail.sourceNoteCode;
                
                String inPolicyNo = p_reqBat.readedDetail.srcXElement.getSingleText(getBankConfig().getValueAsString("inPolicyNo"));
                if (StringUtils.isNotEmpty(inPolicyNo)) {
                	insuPolicyNum = inPolicyNo;
                }
                
                String payPeriod = getBankConfig().getMapValueByKey("payPeriod", p_reqBat.readedDetail.memo);

                String tmpReqBodyDetail = "";
                if ("1988".equals(p_reqBat.reqHeader.transType)) {
                    tmpReqBodyDetail = MessageFormat.format("{0}※{1}※{2}※{3}※{4}※※※\n", oppAct, p_reqBat.readedDetail.payAmount, oppName, insuPolicyNum, p_reqBat.readedDetail.askNumber);
                } else {
                    tmpReqBodyDetail = MessageFormat.format("{0}※{1}※{2}※{3}※{4}※{5}※※※\n", oppAct, p_reqBat.readedDetail.payAmount, oppName, insuPolicyNum, payPeriod, p_reqBat.readedDetail.askNumber);
                }
                sbFileContent.append(tmpReqBodyDetail);
            }

            String tmpReqData = sbFileContent.toString();
            WriteBankLogStep2(tmpReqData);

            // 上传文件名保存本地，查询时用
            String tmpMarkDataDir = getDataFileDirectory(tmpPayDateTime) + File.separator + "bat";
            int maxBatch = 0;
            File dataFileDir = new File(tmpMarkDataDir);
            if (dataFileDir.exists()) {
                int len = dataFileDir.listFiles().length;
                if (len > 0) {
                    maxBatch = len + 1;
                } else {
                    maxBatch = 1;
                }
            } else {
                maxBatch = 1;
            }

            // 文件名命名规则: UBD/UBP_保险公司编号(4位) _机构代码（4位）_日期（8位）_序号（2位）
            String tmpUpFilePrefix = trxCode + "_" + bankFront.corpNo + "_" + bankFront.org + "_" + tmpPayDate + "_" + String.format("%2s", maxBatch).replace(" ", "0");
            String tmpUpFileName = tmpUpFilePrefix + ".TXT";
            String tmpLocalMarkPath = StringHelper.trimEnd(tmpMarkDataDir, File.separator) + File.separator + p_reqBat.reqBatchNO + ".TXT";
            WriteBankLogLn2("批次号映射文件路径: " + tmpLocalMarkPath);
            FileHelper.writeFile(tmpLocalMarkPath, tmpUpFilePrefix, getCharset());

            String tmplocalFilePath = getTempFileDirectory(tmpPayDateTime) + File.separator + tmpUpFileName;
            WriteBankLogLn2("批量代收付请求文件保存本机路径:"+tmplocalFilePath);
            FileHelper.writeFile(tmplocalFilePath, tmpReqData, getCharset());

            //上送银保通服务器
            FtpSet ftpSet = bankFront.getFtpSet("bat");
            //MixFtp mixFtp = new MixFtp(ftpSet);
            //FtpReceiver ftpReceiver = mixFtp.uploadFileToDir(tmplocalFilePath, ftpSet.upDir, tmpUpFileName);
            
            FtpReceiver ftpReceiver = null;
            String requestType = getBankConfig().getValueAsString("requestType");
            if (requestType != null && "SFTP".equals(requestType)) {
                SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
                String sftpFilePath = StringHelper.trimEnd(ftpSet.upDir, "/") + "/" + tmpUpFileName;
                ftpReceiver = sftpPortClient.uploadFile("", tmplocalFilePath, sftpFilePath);
                sftpPortClient.disconnect();
            } else {
                FtpPortClient ftpPortClient = new FtpPortClient(ftpSet);
                ftpPortClient.setLocalPassiveMode();
                ftpReceiver = ftpPortClient.uploadFile(tmplocalFilePath, tmpUpFileName);
                ftpPortClient.disconnect();
            }

            retAts.respCode = "0";
            if (!ftpReceiver.isCompleted) {
                retAts.respCode = "-1";
                retAts.respInfo = ftpReceiver.connMsg;
            } else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
                retAts.respInfo = "上传失败";
                retAts.transState = "BatchFailed";
                retAts.payInfoCode = "E9999";
            } else {
                retAts.respInfo = "上传成功";
                retAts.transState = "Uploaded";
                retAts.payInfoCode = "I4001";

                String[] tmpStrRet = WtpFileUtil.wtpUpload(bankFront.serverURL, tmpUpFileName, ftpSet.upDir);
                if (tmpStrRet[0].length() == 0) {
                    retAts.respCode = "0";
                    retAts.respInfo = "文件已上送银保通服务器并已发送通知给银保通";
                    retAts.reqSeqID = p_reqBat.reqBatchNO;
                    retAts.transState = "UBPD+uploaded";
                    retAts.payInfoCode = "uploaded";
                } else {
                    retAts.respCode = "-1";
                    retAts.reqSeqID = p_reqBat.reqBatchNO;
                    retAts.respInfo = "文件通知失败，原因:" + tmpStrRet[1];
                    retAts.transState = PaymentState.FAIL_Batch;
                    retAts.payInfoCode = FailCode.E9981;
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeRetToATS();
        return retAts;
    }

    public RetAtsQryBatPayRec d_QryBatPayRec(ReqQryBatPayRec p_reqQryBat) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_reqQryBat.reqHeader);
        retAts.reqSeqID = p_reqQryBat.reqBatchNO;

        try {
            Date tmpPaySendTime = getDayCutTime(p_reqQryBat.getBgnDateTime());
            String tmpMarkDataDir = getDataFileDirectory(tmpPaySendTime) + File.separator + "bat";
            String tmpLocalMarkPath = StringHelper.trimEnd(tmpMarkDataDir, File.separator) + File.separator + p_reqQryBat.reqBatchNO + ".TXT";
            WriteBankLogLn2("本地批次号映射文件路径: " + tmpLocalMarkPath);

            File localMarkFile = new File(tmpLocalMarkPath);
            if (!localMarkFile.exists()) {
                retAts.respCode = "-1";
                retAts.respInfo = "批次流水映射文件未生成，尚未回盘!";
                retAts.writeAfterDetail();
                return retAts;
            }
            String trxCode = "DBP";
            if ("1998".equals(p_reqQryBat.reqHeader.transType)) {
                trxCode = "DBD";
            }
            String tmpDownFileName = "";
            String tmpDownFilePrefix = FileHelper.readFileText(tmpLocalMarkPath, getCharset());
            if (StringHelper.hasAnyChar(tmpDownFilePrefix)) {
                tmpDownFileName = trxCode + tmpDownFilePrefix.substring(3) + ".TXT";
            } else {
                tmpDownFileName = trxCode + tmpDownFilePrefix+ ".TXT";
            }

            Map<String, Object> tmpRetMap = WtpFileUtil.wtpDownload(bankFront.serverURL, tmpDownFileName);

            WriteBankLogLn("wtp下载结果map内容:\r\n");
            Iterator<String> iterator = tmpRetMap.keySet().iterator();
            while(iterator.hasNext()) {
                String retMapKey = iterator.next();
                WriteBankLogLn(retMapKey+":" +tmpRetMap.get(retMapKey));
            }

            String mapRespCode = (String) tmpRetMap.get("RespCode");
            if (StringHelper.isNullOrEmpty(mapRespCode)) {
                // 下载成功

                Map<String,String> ftpMap = (Map<String, String>) tmpRetMap.get("Result");
                WriteBankLogLn("wtp下载结果Result内容:\r\n");
                Iterator<String> tmpIterator = ftpMap.keySet().iterator();
                while(tmpIterator.hasNext()) {
                    String retMapKey = tmpIterator.next();
                    WriteBankLogLn(retMapKey+":" +ftpMap.get(retMapKey));
                }

                FtpSet ftpSet = new FtpSet();
                ftpSet.serverIP = ftpMap.get("wtpHost");
                ftpSet.port = Integer.parseInt(ftpMap.get("wtpPort"));
                ftpSet.userName = ftpMap.get("userName");
                ftpSet.userPassword = ftpMap.get("passWord");
                ftpSet.downDir = ftpMap.get("filePath");

                MixFtp mixFtp = new MixFtp(ftpSet);
                String tmpLocalFilePath = createTempFileDirectory(tmpPaySendTime) + File.separator + tmpDownFileName;
                WriteBankLogLn2("批次结果文件保存本机路径:"+tmpLocalFilePath);
                FtpReceiver ftpReceiver = mixFtp.downloadFileFromDir(ftpSet.downDir, tmpDownFileName, tmpLocalFilePath);
                if (ftpReceiver.isCompleted) {
                    String tmpStrRet = FileHelper.readFileText(tmpLocalFilePath, getCharset());
                    WriteBankLogLn2("本地批次结果文件内容:\r\n" + tmpStrRet);
                    if (StringHelper.hasAnyChar(tmpStrRet)) {
                        retAts.respCode = "0";
                        retAts.reqSeqID = p_reqQryBat.reqBatchNO;

                        StringReader strReader = new StringReader(tmpStrRet);
                        BufferedReader tmpReader = new BufferedReader(strReader);
                        tmpReader.readLine();
                        while (true) {
                            String eachline = tmpReader.readLine();
                            if (eachline == null) {
                                break;
                            }
                            String[] eachNodes = eachline.split("※");
                            RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();

                            tmpRetDetail.postScript = eachNodes[6].trim();
                            tmpRetDetail.payAmount = eachNodes[1].trim();

                            if ("1988".equals(p_reqQryBat.reqHeader.transType)) {
                                tmpRetDetail.recAct = eachNodes[0].trim();
                                tmpRetDetail.recName = eachNodes[2].trim();
                            } else {
                                tmpRetDetail.payAct = eachNodes[0].trim();
                                tmpRetDetail.payName = eachNodes[2].trim();
                            }
                            String tmpRespCode = eachNodes[4].trim();
                            //DBP 表示 Down Batch Payment (批量扣款)
                            // 0-失败 1-成功
                            tmpRetDetail.result = "DBPD+" + tmpRespCode;
                            String[] bkInfo = eachNodes[5].trim().split(":");
                            if (bkInfo.length > 1) {
                                tmpRetDetail.payInfoCode = bkInfo[0];
                                tmpRetDetail.memo = bkInfo[1];
                            } else if("".equals(eachNodes[5].trim())&&"1".equals(tmpRespCode)) {
                                tmpRetDetail.payInfoCode = "0";
                                tmpRetDetail.memo = "成功";
                            }else {
                                tmpRetDetail.payInfoCode = eachNodes[5].trim();
                                tmpRetDetail.memo = eachNodes[5].trim();
                            }

                            retAts.writeRetDetail(tmpRetDetail);
                        }
                        tmpReader.close();
                        strReader.close();
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = "本地批次结果文件内容为空!";
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "批次结果文件下载失败:" + ftpReceiver.connMsg;
                }
            } else {
                // 下载失败
                retAts.respCode = "0";
                retAts.respInfo = (String) tmpRetMap.get("RespInfo");
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9981;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeAfterDetail();
        return retAts;
    }
}